﻿//
//  aac_adts.h
//  aac
//
//  Created by cl.zhan on 17/5/22.
//  email:zhanchonglongba@126.com/690759587
//
//

#ifndef AAC_ADTS_H_H
#define AAC_ADTS_H_H

#if defined(WIN32)
#include <windows.h>
#endif

#include <vector>
#include <string>
#include <stdint.h>


// aac adts 的头一般7个字节， 分两部分：

typedef struct adts_fixed_header
{
    //12 bslbf 同步字The bit string ‘1111 1111 1111’，说明一个ADTS帧的开始
    unsigned int syncword;

    //1 bslbf   MPEG 标示符, 设置为1
    unsigned int id;

    //2 uimsbf Indicates which layer is used. Set to ‘00’
    unsigned int layer;
    //1 bslbf  表示是否误码校验
    unsigned int protection_absent;

    //2 uimsbf  表示使用哪个级别的AAC，如01 Low Complexity(LC)--- AACLC
    unsigned int profile;
    //4 uimsbf  表示使用的采样率下标
    unsigned int sampling_frequency_index;
    //1 bslbf
    unsigned int private_bit;

   //3 uimsbf  表示声道数
    unsigned int channel_configuration;
    //1 bslbf
    unsigned int original_copy;
    //1 bslbf
    unsigned int home;
} adts_fixed_header; // length : 28 bits


typedef struct adts_variable_header
{
    //1 bslbf
    unsigned int copyright_identification_bit;
    //1 bslbf

    unsigned int copyright_identification_start;

    // 13 bslbf  一个ADTS帧的长度包括ADTS头和raw data block
    unsigned int aac_frame_length;

    //11 bslbf     0x7FF 说明是码率可变的码流
    unsigned int adts_buffer_fullness;

    /*no_raw_data_blocks_in_frame 表示ADTS帧中有number_of_raw_data_blocks_in_frame + 1个AAC原始帧.
        所以说number_of_raw_data_blocks_in_frame == 0
        表示说ADTS帧中有一个AAC数据块并不是说没有。(一个AAC原始帧包含一段时间内1024个采样及相关数据)
        */


    //2 uimsfb
    unsigned int number_of_raw_data_blocks_in_frame;
} adts_variable_header; // length : 28 bits



class CAdtsHeader
{
public:
    CAdtsHeader(char *fileName);
    CAdtsHeader();
    ~CAdtsHeader();

    /*设置adts头信息
     *channel_cfg    声道数
     *sampling_fre   采样率下标
     *profile        AAC的级别
     */
    //void SetAdtsInfo(uchar_t channel_cfg, uchar_t sampling_fre, uchar_t profile );

    /*设置 aac_stream_len ACC原始流长度*/
    void SetAacFrameLength( int32_t aac_stream_len );

    int	 find_Adts_fff2();

    int  PrintfAdtsInfo();

    //Open API
    int ParseADTSBitstream();

private:
      adts_fixed_header fixed_header;
      adts_variable_header variable_header;



      FILE	*m_inputFile;
      FILE	*m_outFile;
      std::string m_fileName;
      std::vector<uint8_t> m_nalVec;

};


#endif // AAC_ADTS

